﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Diagnostics.Contracts;
using System.Linq;
using System.Text;
using System.Threading;

namespace UPNP.IO.ValueConverters
{
    public sealed class ValueConverterManager
    {
        #region instance

        private static readonly Lazy<ValueConverterManager> _instance = new Lazy<ValueConverterManager>(
            () => new ValueConverterManager(),
            true
            );

        public static ValueConverterManager Instance
        {
            get { return _instance.Value; }
        }

        #endregion

        private readonly Hashtable _deviceValueConverters = new Hashtable();

        public IDeviceValueConverter GetDeviceValueConverter(string upnpType)
        {
            Contract.Requires(!string.IsNullOrEmpty(upnpType));

            var v = _deviceValueConverters[upnpType.ToLower()];

            if (v == null)
                throw new ArgumentException("unsupported upnp device value type: " + upnpType, "upnpType");

            return (IDeviceValueConverter)v;
        }

        private ValueConverterManager()
        {
            // add device value converters
            _deviceValueConverters.Add("string", new DeviceStringConverter());
            _deviceValueConverters.Add("char", new DeviceCharConverter());
            _deviceValueConverters.Add("boolean", new DeviceBooleanConverter());
            _deviceValueConverters.Add("ui1", new DeviceUInt1Converter());
            _deviceValueConverters.Add("ui2", new DeviceUInt2Converter());
            _deviceValueConverters.Add("ui4", new DeviceUInt4Converter());
            _deviceValueConverters.Add("i1", new DeviceInt1Converter());
            _deviceValueConverters.Add("i2", new DeviceInt2Converter());

            {
                var c = new DeviceInt4Converter();

                _deviceValueConverters.Add("i4", c);
                _deviceValueConverters.Add("int", c);
            }

            {
                var c = new DeviceReal2Converter();

                _deviceValueConverters.Add("r4", c);
                _deviceValueConverters.Add("float", c);
            }

            {
                var c = new DeviceReal4Converter();

                _deviceValueConverters.Add("r8", c);
                _deviceValueConverters.Add("number", c);
                _deviceValueConverters.Add("fixed.14.4", c);
            }

            {
                var c = new DeviceDateConverter();

                _deviceValueConverters.Add("date", c);
                _deviceValueConverters.Add("datetime", c);
                _deviceValueConverters.Add("datetime.tz", c);
            }

            {
                var c = new DeviceTimeConverter();

                _deviceValueConverters.Add("time", c);
                _deviceValueConverters.Add("time.tz", c);
            }

            _deviceValueConverters.Add("bin.base64", new DeviceBase64Converter());
            _deviceValueConverters.Add("bin.hex", new DeviceHexConverter());
            _deviceValueConverters.Add("uri", new DeviceUriConverter());
            _deviceValueConverters.Add("uuid", new DeviceUuidConverter());
        }

    }
}
